/*******************************************************************************
 * Copyright (c) 2010, 2030 www.mahao.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package cn.itlaobing.eshopmanagement.controller;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/** 
 * ClassName: YZMController <br/> 
 * Function: TODO 功能描述 <br/> 
 * date: 2017年5月31日 下午9:22:03 <br/> 
 * 
 * @author Mmmmm 
 * @version  
 * @since JDK 1.8 
 */
@Controller
@RequestMapping("/auth")  
public class YZMController extends BaseController {
	// 放到session中的KEY 用于验证，验证码输入是否正确
		public static final String RANDOMCODEKEY = "RANDOMVALIDATECODEKEY";
		// 随机
		private static Random random = new Random();
		// 验证码中的字符串 随机产生的字符串
		private static String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		// 设置图片的宽、高、干扰线数量、产生的随机字符数量
		private static int width = 120;
		private static int height = 40;
		private static int lineSize = 60;
		private static int stringNum = 4;

		/**
		 * 获取字体
		 * 
		 * @return 字体
		 */
		private static Font getFont() {
			// font(字体，风格/样式，字号)
			return new Font("Fixedsys", Font.CENTER_BASELINE, 25);
		}

		/**
		 * 获取随机颜色
		 * 
		 * @param fc
		 *            字体颜色
		 * @param bc
		 *            背景颜色
		 * @return 颜色
		 */
		private static Color getRandColor(int fc, int bc) {
			// 参数超过255的话，默认255
			if (fc > 255)
				fc = 255;
			if (bc > 255)
				bc = 255;

			// 设置RGB值
			int r = fc + random.nextInt(bc - fc - 16);
			int g = fc + random.nextInt(bc - fc - 14);
			int b = fc + random.nextInt(bc - fc - 18);
			return new Color(r, g, b);
		}

		/**
		 * 生成随机图片
		 * 
		 * @param request
		 * @param response
		 * @return 
		 */
		 @RequestMapping(value = "/yzm", method = RequestMethod.GET)
		 @ResponseBody
		public static void getRandCode(
				HttpServletRequest request
				, HttpServletResponse response) {
			HttpSession session = request.getSession();
			// 定义一个缓冲图片
			// BufferedImage(宽、高、BufferedImage.TYPE_INT_RGB)
			// BufferedImage.TYPE_INT_RGB表示一个图像，它具有合成整数像素的8位RGB颜色含量
			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
			// Graphics 类是所有图形上下文的抽象基类，
			// 允许应用程序在组件（已经在各种设备上实现）以及闭屏图像上进行绘制。
			// getGraphics() 返回Graphics2D 和 createGraphics()基本相同
			Graphics g = image.getGraphics();
			//填充矩形，设置边框,Rect矩形
			g.fillRect(0, 2, width, height);
			//设置字体
			g.setFont(new Font("Times New Roman",Font.ROMAN_BASELINE,25));
			//设置颜色
			g.setColor(getRandColor(110, 133));
			
			//绘制干扰线
			for(int i = 0; i < lineSize ; i++){
				drowLine(g);
			}
			
			//绘制随机字符串
			String randomString = "";
			for(int i = 0 ; i < stringNum ; i++){
				randomString = drowString(g,randomString,i);
			}
			
			//将随机字符串存到Session中 用于验证
			session.removeAttribute(RANDOMCODEKEY);
			session.setAttribute(RANDOMCODEKEY, randomString);
			//释放此图形上下文及它使用的所有系统资源
			g.dispose();
			//将内存中的图片通过流的形式输出到客户端
			try {
				ImageIO.write(image, "JPEG", response.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		/**
		 * 绘制字符
		 * @param g Graphics 
		 * @param randomString 随机字符串
		 * @param i int
		 * @return
		 */
		private static String drowString(Graphics g ,String randomString,int i){
			//设置字体、颜色
			g.setFont(getFont());
			g.setColor(new Color(random.nextInt(101),random.nextInt(111),random.nextInt(121)));
			//随机字符
			String rand = String.valueOf(getRandomString(random.nextInt(randString.length())));
			//随机字符串,最后验证用的
			randomString += rand;
			//translate(x,y)将图形上下文的原点平移到当前坐标系中的点(x,y)
			g.translate(random.nextInt(7), random.nextInt(6));
			//drawString(str,x,y)使用此图形上下文的当前字体颜色绘制由指定STRING 给定的文本，最左侧字符基于上下文坐标系的(x,y)位置
			//str ---------- 要绘制的String
			//x,y ---------- 字符的坐标
			g.drawString(rand, 22*i, 25);
			return randomString;
		}
		
		/**
		 * 绘制干扰线
		 * @param g
		 */
		private static void drowLine(Graphics g){
			int x1 = random.nextInt(width);
			int y1 = random.nextInt(height);
			int x2 = random.nextInt(13);
			int y2 = random.nextInt(15);
			x2+=x1;
			y2+=y1;
			//drawLine(x1,y1,x2,y2)是使用当前颜色，在点（x1，y1）和点（x2，y2）之间画一条线
			g.drawLine(x1, y1, x2, y2);
		}
		
		/**
		 * 获取随机的字符
		 * @param num 位置
		 * @return 字符
		 */
		private static String getRandomString(int num){
			return String.valueOf(randString.charAt(num));
		}
	
}
